package com.p2l.letterblocks;

import java.util.ArrayList;

import android.app.Activity;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.util.Log;

public class LevelLoader {
	public static final int EASY = 0;
	public static final int NORMAL = 1;
	public static final int HARD = 2;
	
	public static final int ENGLISH = 0;
	public static final int SPANISH = 1;
	public static final int GERMAN = 2;
	public static final int DANISH = 3;
	
	private static String[] keys;
	public static String[] VOWELS;
	
	public static boolean loadLevel(GamePersistor persistor, int levelId, int userId, int difficulty) {
		Database db = new Database(persistor.getApplicationContext());
		SQLiteDatabase sqlite = db.getReadableDatabase();
		keys = persistor.getResources().getStringArray(R.array.keys);
		
		try {
			// get the current levels info
			String select = "SELECT *";
			String where = " WHERE levelId='" + levelId + "'";
			Cursor cursor = db.select(sqlite, select, Database.TABLE_NAME_LEVELS, "", where);
			Level level = db.getLevels(cursor).get(0);
			
			// get bitmaps from drawable
			persistor.getView().setBackground(getBitmap(persistor, level.getBackground()));
			persistor.getView().setBackgroundLayer(getBitmap(persistor, level.getLayer()));
			persistor.getView().setFloor(getBitmap(persistor, level.getFloor()));
			
			SharedPreferences preferences = persistor.getSharedPreferences("LetterBlocks", Activity.MODE_PRIVATE);
			int language = preferences.getInt("language", 0);

			String word = "";
			switch (language) {
			case ENGLISH:
				word = level.getEn();
				VOWELS = persistor.getResources().getStringArray(R.array.vowels_en);
				break;
			case SPANISH:
				word = level.getEs();
				VOWELS = persistor.getResources().getStringArray(R.array.vowels_es);
				break;
			case GERMAN:
				word = level.getDe();
				VOWELS = persistor.getResources().getStringArray(R.array.vowels_de);
				break;
			case DANISH:
				word = level.getDk();
				VOWELS = persistor.getResources().getStringArray(R.array.vowels_da);
				break;
			default:
				word = level.getEn();
				VOWELS = persistor.getResources().getStringArray(R.array.vowels_en);
				break;
			}
			persistor.getModel().setWord(word);
			
			// get all the objects in the current level
			select = "SELECT *";
			where = " WHERE levelId='" + levelId + "'";
			cursor = db.select(sqlite, select, Database.TABLE_NAME_OBJECTS, "", where);
			ArrayList<P2LObject> objects = db.getObjects(cursor);
			
			Bear bear = null;
			Coin coin = null;
			ArrayList<Block> blocks = new ArrayList<Block>();
			ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
			
			// go trough all the objects parsed from xml
			int index = 0;
			int length = word.length();
			if (difficulty == NORMAL)
				length += (length > 6 ? length & 8 : 2);
			else if (difficulty == HARD)
				length = 8;
			
			for (P2LObject o : objects) {
				switch (o.getType()) {
				// if object is a type of Bear
				case XmlParser.TYPE_BEAR:
					bear = new Bear(o.getX(), o.getY(), o.getHeight(), o.getWidth(), getBitmap(persistor, o.getImage()));
					break;
				// if object is a type of Coin
				case XmlParser.TYPE_COIN:
					coin = new Coin(o.getX(), o.getY(), o.getHeight(), o.getWidth(), getBitmap(persistor, o.getImage()));
					break;
				// if object is a type of Block
				case XmlParser.TYPE_BLOCK:
					if (index < length) {
						char letter = (index < word.length() ? word.charAt(index) : getRandomChar(persistor, language));
						boolean found = false;
						int i = 0;
						
						while (!found && i < VOWELS.length) {
							if (letter == VOWELS[i].charAt(0))
								found = true;
							else
								i++;
						}
						
						blocks.add(new Block(persistor, o.getX(), o.getY(), o.getHeight(), o.getWidth(), (found ? BitmapFactory.decodeResource(persistor.getResources(), R.drawable.letterblock_red) : BitmapFactory.decodeResource(persistor.getResources(), R.drawable.letterblock_blue)), letter, GamePersistor.SCALE, (found ? Color.RED : Color.BLUE)));
						index++;
					}
					break;
				// if object is a type Obstacle
				case XmlParser.TYPE_OBSTACLE:
					obstacles.add(new Obstacle(o.getX(), o.getY(), o.getHeight(), o.getWidth(), getBitmap(persistor, o.getImage())));
					break;
				}
			}
			
			// ArrayList to Array
			Block[] bArray = new Block[blocks.size()];
			for (int i = 0; i < blocks.size(); i++)
				bArray[i] = blocks.get(i);
			
			// ArrayList to Array
			Obstacle[] oArray = new Obstacle[obstacles.size()];
			for (int i = 0; i < obstacles.size(); i++)
				oArray[i] = obstacles.get(i);
			
			// send the parsed objects to the GameModel
			persistor.getModel().setBlocks(bArray);
			persistor.getModel().setObstacles(oArray);
			persistor.getModel().setBear(bear);
			
			if (coin != null) {
				select = "SELECT *";
				where = " WHERE levelId='" + persistor.levelId + "' AND userId='" + persistor.userId + "' AND language='" + language + "'";
				cursor = db.select(sqlite, select, Database.TABLE_NAME_LEVELS_COMPLETED, "", where);
				ArrayList<LevelCompleted> levels_completed = db.getLevelsCompleted(cursor);
				
				int i = 0;
				boolean found = false;
				
				while (!found && i < levels_completed.size()) {
					if (levels_completed.get(i).isCoin())
						found = true;
					else
						i++;
				}
				
				if (!found)
					persistor.getModel().setCoin(coin);
				
				levels_completed.clear();
				levels_completed = null;
			}
			
			// set bear items
			int savedId = preferences.getInt("userId", -1);
			if (savedId == userId && savedId != -1) {
				for (int i = 0; i < keys.length; i++) {
					String str = preferences.getString("string_" + keys[i], "");
				    if (!str.equals("")) {
						switch (i) {
						case 0:
							Bitmap head = Server.loadBitmap(persistor, Server.FOLDERS[i], str + "_game.png");
							if (head != null)
								bear.setHead(head);
							else
								persistor.runBitmapTask(Server.URL_HOME + Server.FOLDERS[i] + str + "_game.png", str, i);
							break;
						case 1:
							Bitmap body = Server.loadBitmap(persistor, Server.FOLDERS[i], str + "_game.png");
							if (body != null)
								bear.setBody(body);
							else
								persistor.runBitmapTask(Server.URL_HOME + Server.FOLDERS[i] + str + "_game.png", str, i);
							break;
						case 2:
							Bitmap legs = Server.loadBitmap(persistor, Server.FOLDERS[i], str + "_game.png");
							if (legs != null)
								bear.setLegs(legs);
							else
								persistor.runBitmapTask(Server.URL_HOME + Server.FOLDERS[i] + str + "_game.png", str, i);
							break;
						case 3:
							Bitmap belt = Server.loadBitmap(persistor, Server.FOLDERS[i], str + "_game.png");
							if (belt != null)
								bear.setBelt(belt);
							else
								persistor.runBitmapTask(Server.URL_HOME + Server.FOLDERS[i] + str + "_game.png", str, i);
							break;
						case 4:
							Bitmap accessories = Server.loadBitmap(persistor, Server.FOLDERS[i], str + "_game.png");
							if (accessories != null)
								bear.setAccessories(accessories);
							else
								persistor.runBitmapTask(Server.URL_HOME + Server.FOLDERS[i] + str + "_game.png", str, i);
							break;
						}
				    }
				    str = null;
				}
			}

			obstacles.clear();
			objects.clear();
			blocks.clear();

			preferences = null;
			obstacles = null;
			objects = null;
			cursor = null;
			blocks = null;
			select = null;
			level = null;
			where = null;
			
			persistor.getModel().getEndLevel().setWord(word);
			word = null;
			
			return true;
		} catch (Exception e) {
			Log.e("LetterBlocks", e.toString());
			return false;
		} finally {
			db.close();
			db = null;
			sqlite = null;
		}
	}
	
	private static Bitmap getBitmap(GamePersistor persistor, String resource) {
		try {
			int id = persistor.getResources().getIdentifier(resource, "drawable", persistor.getPackageName());
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inScaled = false;
			return BitmapFactory.decodeResource(persistor.getResources(), id, options);
		} catch (OutOfMemoryError e) {
			return null;
		}
	}
	
	private static char getRandomChar(GamePersistor persistor, int language) {
		int text = 0;
		switch (language) {
		case LevelLoader.ENGLISH:
			text = R.array.alphabet_en;
			break;
		case LevelLoader.SPANISH:
			text = R.array.alphabet_es;
			break;
		case LevelLoader.GERMAN:
			text = R.array.alphabet_de;
			break;
		case LevelLoader.DANISH:
			text = R.array.alphabet_da;
			break;
		default:
			text = R.array.alphabet_en;
			break;
		}
		
		String[] alphabet = persistor.getResources().getStringArray(text);
		char c;
		
		int index = (int) (Math.random() * alphabet.length);
		c = alphabet[index].charAt(0);
		
		return c;
	}
}
